// ============================== 导入依赖 ============================== //

import CORE from '@/CORE'
import Client from '@api/questionnaire/api/IbQuestionnaireApi'

import ComClass from '@api/ComQuery'
import ListClass from '@api/questionnaire/model/QuestionnaireQueryReq'
import OneClass from '@api/questionnaire/model/QuestionnaireDetailReq'
import AddClass from '@api/questionnaire/model/QuestionnaireReq'
import DelClass from '@api/questionnaire/model/QuestionnaireUpdateReq'
import BaseClass from '@api/questionnaire/model/QuestionnaireDto'
import QuestionClass from '@api/questionnaire/model/QuestionnaireQuestionDto'
import OptionClass from '@api/questionnaire/model/QuestionnaireOptionDto'
import ConfigClass from '@api/questionnaire/model/RepeatConfigDto'

const EditClass = AddClass
const StatusClass = DelClass

const CLIENT = CORE.grpcCLIENT(Client)
const COM = [ComClass, 'comQuery']

const OPTION = [OptionClass, 'optionList', 1]

const SUB_QUESTION = [QuestionClass, 'questionList', 1]
const QUESTION = [QuestionClass, 'questionList', 1, (dto, obj) => CORE.grpcDTO(dto, obj, OPTION, SUB_QUESTION)]

const CONFIG = [ConfigClass, 'repeatConfig', 1]

const BASE = [BaseClass, 'dto', null, (dto, obj) => CORE.grpcDTO(dto, obj, CONFIG, QUESTION)]

// ============================== 导出远程接口 ============================== //

export default {
  // —————————————————————————————— 列表 —————————————————————————————— //

  async getList(param, TIP = '查询列表') {
    const DTO = CORE.grpcDTO(ListClass, param, COM)
    const resp = await CORE.grpc(TIP, CLIENT, 'questionnaireQuery', DTO)
    return [resp.comQuery.totalCount, resp.dto || []]
  },
  transList(arr, { state: { DICT: { TITLE_BTN } } }) {
    arr.forEach((item) => {
      item.title = TITLE_BTN.reduce((str, [k, v, u]) => str.replace(new RegExp(`${k}${u}`, 'g'), v), item.title)
      item.sendUserNum = item.sendUsers.length
      item.startStatus = item.questionnaireType === 1 ? undefined : item.startStatus
    })
    return arr
  },

  // —————————————————————————————— 单项 —————————————————————————————— //

  async getOne(one, TIP = '查询详情') {
    const DTO = CORE.grpcDTO(OneClass, { questionnaireId: one.id })
    const resp = await CORE.grpc(TIP, CLIENT, 'questionnaireDetail', DTO)
    return resp.dto || one
  },
  transOne(obj, { state: { DICT: { TITLE_BTN = [] } } }) {
    const noMap = {}
    const questionList = obj.questionList.map((question) => {
      // 记录编号与 ID 映射
      noMap[question.no] = question.id
      // 解析评分题的提示
      if (question.type === 'rate') {
        const tipMap = JSON.parse(question.tip)
        Array(10).fill().map((_, i) => (question[`tip_${i + 1}`] = tipMap[i + 1] || ''))
      }
      // 转换表格问答题的子问题为三层结构
      if (question.type === 'textareaTable') {
        const { optionList: options, questionList: subs } = question
        const subLength = subs.length / options.length | 0
        question.questionList = subs.slice(0, subLength).map((sub, j) => {
          const subList = Array(options.length).fill().map((_, k) => subs[k * subLength + j])
          return { ...sub, questionList: subList }
        })
      }
      return { ...question, checkList: [], key: question.key || question.id }
    })

    questionList.forEach(({ no, type, optionList, questionList: subList }) => {
      optionList.forEach((option) => {
        option.key = option.key || option.id
        if (['radio', 'radioTable', 'checkbox', 'checkboxTable'].includes(type)) {
          option.label = String.fromCharCode(option.no + 64)
          option.image = option.images ? option.images.split(',') : []
          option.imgList = option.image.map((url) => CORE.image(url))
          option.selectMulti = option.related ? option.related.split(',').map((item) => noMap[item]) : []
          option.selectMulti.forEach((item) => {
            const matched = questionList.find(({ id }) => id === item)
            if (matched) matched.checkList.push([no, option.label])
          })
        }
      })
      subList.forEach((sub) => {
        sub.key = sub.key || sub.id
      })

      if (type === 'radio') obj[`no_${no}`] = undefined
      if (type === 'radioTable') subList.forEach((sub) => (obj[`no_${no}_${sub.no}`] = undefined))

      if (type === 'checkbox') obj[`no_${no}`] = ''
      if (type === 'checkboxTable') subList.forEach((sub) => (obj[`no_${no}_${sub.no}`] = ''))

      if (type === 'textarea') obj[`no_${no}`] = ''
      if (type === 'textareaTable') subList.forEach((sub) => (obj[`no_${no}_${sub.no}`] = ''))

      if (type === 'rate') obj[`no_${no}`] = undefined
    })

    const title = TITLE_BTN.reduce((str, [k, v, u]) => str.replace(new RegExp(`${k}${u}`, 'g'), v), obj.title)
    const sendDate = obj.sendTime ? CORE.dateStr(obj.sendTime) : ''
    const sendHour = obj.sendTime ? CORE.timeStr(obj.sendTime).slice(11, -3) : ''
    const config = obj.repeatConfig || {}
    const repeatConfig_time = config.time || undefined
    const repeatConfig_week = config.week || []
    const repeatConfig_month = (config.month || []).concat(config.lastMonthDay ? [99] : [])

    return {
      ...obj,
      title,
      sendDate,
      sendHour,
      repeatConfig_time,
      repeatConfig_week,
      repeatConfig_month,
      questionList,
    }
  },

  // —————————————————————————————— 增 —————————————————————————————— //

  transAdd(one, { state: { DICT: { TITLE_BTN } } }) {
    const keyMap = one.questionList.reduce((map, { key }, i) => (map[key] = i + 1) && map, {})

    const questionList = one.questionList.map(({ type, optionList: options, questionList: subs, ...other }, i) => {
      const optionList = options.map((option, j) => ({
        ...option,
        no: j + 1,
        images: (option.image || []).join(','),
        related: (option.selectMulti || []).map((key) => keyMap[key]).join(','),
      }))

      const subList = subs.map((sub, j) => ({ ...sub, no: j + 1 }))
      if (type === 'textareaTable') { // 表格问答题，子问题存储为扩倍的数量
        Array(options.length - 1).fill().map((_, j) => {
          const moreList = subs.map((sub, k) => ({ ...sub, no: (j + 1) * subs.length + k + 1 }))
          subList.push(...moreList)
        })
      }

      return { ...other, type, no: i + 1, optionList, questionList: subList }
    })

    const title = TITLE_BTN.reduce((str, [k, v, u]) => str.replace(new RegExp(v, 'g'), `${k}${u}`), one.title)
    const repeatConfig = {
      time: one.repeatConfig_time,
      week: one.repeatConfig_week,
      month: one.repeatConfig_month.filter((item) => item !== 99),
      lastMonthDay: one.repeatConfig_month.some((item) => item === 99),
    }

    return { ...one, title, repeatConfig, questionList }
  },
  async add(one, TIP = '新增') {
    const DTO = CORE.grpcDTO(AddClass, one, BASE)
    await CORE.grpc(TIP, CLIENT, 'questionnaireSave', DTO)
    return CORE.grpcOK(TIP)
  },

  // —————————————————————————————— 改 —————————————————————————————— //

  transEditToAdd: true,
  async edit(one, TIP = '修改') {
    const DTO = CORE.grpcDTO(EditClass, one, BASE)
    await CORE.grpc(TIP, CLIENT, 'questionnaireSave', DTO)
    return CORE.grpcOK(TIP)
  },

  // —————————————————————————————— 删 —————————————————————————————— //

  async del({ id }, TIP = '删除') {
    const DTO = CORE.grpcDTO(DelClass, { questionnaireId: id })
    await CORE.grpc(TIP, CLIENT, 'questionnaireDelete', DTO)
    return CORE.grpcOK(TIP)
  },

  // —————————————————————————————— 修改状态 —————————————————————————————— //

  async updateStatus({ id, status }, TIP = '修改状态') {
    const DTO = CORE.grpcDTO(StatusClass, { questionnaireId: id, status })
    await CORE.grpc(TIP, CLIENT, 'questionnaireUpdateStatus', DTO)
    return CORE.grpcOK(TIP)
  },

  // —————————————————————————————— 修改启动状态 —————————————————————————————— //

  async updateStartStatus({ id, startStatus }, TIP = '修改启动状态') {
    const DTO = CORE.grpcDTO(StatusClass, { questionnaireId: id, startStatus })
    await CORE.grpc(TIP, CLIENT, 'questionnaireUpdateStartStatus', DTO)
    return CORE.grpcOK(TIP)
  },
}
